﻿using NHibernate;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using SevenDigital.EndUserManagement.Core;
using SevenDigital.EndUserManagement.Core.Exceptions;
using SevenDigital.EndUserManagement.Core.Repository;

namespace SevenDigital.EndUserManagement.Tests.Repository
{
	[TestFixture]
	public class UserRepositoryFixture : BaseFixture
	{
		private UserRepository _userRepository;
		private const string EXPECTED_USER_EMAIL = "test1@7digital.com";

		protected override void mainSetup() {
			_userRepository = new UserRepository(GetSessionFactory());
			//_userRepository.Session = GetSession();
		}
	
		[Test]
		public void should_return_user_by_email() {
			createUser(new User { Email = EXPECTED_USER_EMAIL, Password = "helloWorld" });
			var user = _userRepository.FindUserByEmail(EXPECTED_USER_EMAIL);
			Assert.That(user, Is.Not.Null);
		}

		[Test]
		[ExpectedException(ExceptionType = typeof(EntityNotFoundException), 
			ExpectedMessage ="No user found")]
		public void should_return_EntityNotFoundException_when_there_no_match() {
			clearRepository();
			_userRepository.FindUserByEmail(EXPECTED_USER_EMAIL);
		}

		[Test]
		public void should_return_most_recent_user_if_more_than_one_user_returned_with_similar_email() {
			createUser(new User { Email = EXPECTED_USER_EMAIL, Password = "user1" });
			createUser(new User { Email = EXPECTED_USER_EMAIL, Password = "user2" });

			var user = _userRepository.FindUserByEmail(EXPECTED_USER_EMAIL);
			Assert.That(user, Is.Not.Null);

			Assert.That(user.Password, Is.EqualTo("user2"));
		}

		private void createUser(User user) {
			using (ISession session = GetSession()) {
				using (ITransaction transaction = session.BeginTransaction()) {
					session.Save(user);
					session.Flush();
					transaction.Commit();
				}
			}
		}

		private void clearRepository() {
			using (ISession s = GetSession()) {
				using (ITransaction transaction = s.BeginTransaction()) {
					//var user = new User { Email = EXPECTED_USER_EMAIL, Password = "HelloWorld" };

					s.CreateQuery("Delete from User u")
						.ExecuteUpdate();
					transaction.Commit();
				}
			}
		}
	}
}